package com.tlgen.orm.model;

import com.tlgen.orm.components.autoFill.BatchLifecycleExecutor;
import com.tlgen.orm.components.autoFill.EntityImplHandlerLoader;
import com.tlgen.orm.components.autoFill.LifecycleExecutor;
import com.tlgen.orm.enums.FillType;
import com.tlgen.orm.service.impl.EntityImpl;
import com.tlgen.orm.support.QueryOperator;
import com.tlgen.orm.utils.orm.SQLGenUtils;

import java.util.List;

import static com.tlgen.orm.utils.orm.ORMUtils.getQueryOperator;

public class Model {

    public static <T> List<T> select(Class<T> tClass) {
        return SQLGenUtils.select(tClass);
    }

    public static <T> List<T> select(Object object) {
        return SQLGenUtils.select(getQueryOperator(object), (Class<T>) object.getClass());
    }

    public static <T> List<T> select(QueryOperator<T> queryOperator, Class<T> tClass) {
        return SQLGenUtils.select(queryOperator, tClass);
    }

    public static <T> T selectById(Object id, Class<T> tClass) {
        return SQLGenUtils.selectById(id, tClass);
    }

    public static <T> T selectOne(QueryOperator<T> queryOperator, Class<T> tClass) {
        return SQLGenUtils.selectOne(queryOperator, tClass);
    }

    public static <T> T selectOne(Object object, QueryOperator<T> queryOperator) {
        return SQLGenUtils.selectOne(getQueryOperator(object), queryOperator, (Class<T>) object.getClass());
    }

    public static <T> T selectOne(Object object) {
        return SQLGenUtils.selectOne(getQueryOperator(object), (Class<T>) object.getClass());
    }

    public static <T> List<T> tree(Class<T> tClass) {
        return SQLGenUtils.tTree(tClass);
    }

    public static <T> void save(Object o) {
        LifecycleExecutor.execute(
                o,
                FillType.INSERT,
                (entity, impl) -> impl.beforeSave(entity), // 前置操作
                SQLGenUtils::save,         // 数据库操作
                (entity, impl, id) -> impl.afterSave(entity) // 后置操作
        );
    }

    public static <T> void saveBatch(List<T> models) {
        // 批量自动填充
        BatchLifecycleExecutor.executeBatch(
                models,
                FillType.INSERT,
                (entity, impl) -> impl.beforeSave(entity), // 前置操作
                (SQLGenUtils::saveBatch),                    // 批量数据库操作
                (tList, impl) -> {             // 后置操作
                    for (T entity : tList) {
                        impl.afterSave(entity); // 注意：批量操作可能无法获取单个ID
                    }
                }
        );
    }

    public static <T> void update(Object o) {
        LifecycleExecutor.execute(
                o,
                FillType.UPDATE,
                (entity, impl) -> impl.beforeUpdate(entity), // 前置操作
                entity -> {
                    SQLGenUtils.update(entity);
                    return null; // 无返回值
                },
                (entity, impl, result) -> impl.afterUpdate(entity) // 后置操作
        );
    }

    public static <T> void update(QueryOperator<T> queryOperator, Object o) {
        LifecycleExecutor.execute(
                o,
                FillType.UPDATE,
                (entity, impl) -> impl.beforeUpdate(entity), // 前置操作
                entity -> {
                    SQLGenUtils.update(queryOperator, o);
                    return null; // 无返回值
                },
                (entity, impl, result) -> impl.afterUpdate(entity) // 后置操作
        );
    }

    public static <T> void updateBatch(List<T> models) {
        // 批量自动填充
        BatchLifecycleExecutor.executeBatch(
                models,
                FillType.UPDATE,
                (entity, impl) -> impl.beforeUpdate(entity), // 前置操作
                (SQLGenUtils::updateBatch),                    // 批量数据库操作
                (tList, impl) -> {             // 后置操作
                    for (T entity : tList) {
                        impl.afterUpdate(entity); // 注意：批量操作可能无法获取单个ID
                    }
                }
        );
    }

    public static <T> void updateSelective(Object o) {
        SQLGenUtils.updateSelective(o);
    }

    public static <T> void updateSelective(QueryOperator<T> queryOperator, Object o) {
        SQLGenUtils.updateSelective(queryOperator, o);
    }

    public static void deleteById(Object id, Class<?> tclass) {
        EntityImpl<?> handler = EntityImplHandlerLoader.getHandler(tclass);
        handler.beforeDelete(id);
        SQLGenUtils.deleteById(id, tclass);
        handler.afterDelete(id);
    }

    public static <T> void deleteLogicalById(Object id, Class<T> tclass) {
        EntityImpl<?> handler = EntityImplHandlerLoader.getHandler(tclass);
        handler.beforeLogicalDelete(id);
        SQLGenUtils.deleteLogicalById(id, tclass);
        handler.afterLogicalDelete(id);
    }

    public static <T> void delete(QueryOperator<T> queryOperator, Class<T> tclass) {
        SQLGenUtils.delete(queryOperator, tclass);
    }

    public static <T> void delete(Class<T> tclass) {
        SQLGenUtils.delete(tclass);
    }


    public static <T> void deleteByIds(List<T> ids, Class<T> tClass) {
        SQLGenUtils.deleteByIds(ids, tClass);
    }

    public static <T> PageResult<T> selectPage(Integer pageNum, Integer pageSize, QueryOperator<T> queryOperator, Class<T> tClass) {
        return SQLGenUtils.selectPage(pageNum, pageSize, queryOperator, tClass);
    }

    public static <T> PageResult<T> selectCursorPage(Integer pageSize, String nextCursor, Boolean orderByDesc, QueryOperator<T> queryOperator, Class<T> tClass) {
        return SQLGenUtils.selectCursorPage(pageSize, nextCursor, orderByDesc, queryOperator, tClass);
    }

}
